package com.zy.design.pattern.proxy.rpc.server;

import com.zy.design.pattern.proxy.rpc.RPCMeat;
import lombok.SneakyThrows;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.Socket;

/**
 * @author zhaoyi
 * @date 2021/4/8 16:42
 */
public class ServerThread extends Thread {

    private Socket socket;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @SneakyThrows
    @Override
    public void run() {
        InputStream is = null;
        OutputStream os = null;
        ObjectInputStream ObjectInput = null;
        ObjectOutputStream objectOutputStream = null;
        try {
            is = socket.getInputStream();
            ObjectInput = new ObjectInputStream(is);
            RPCMeat rpcMeat = (RPCMeat) ObjectInput.readObject();

            /**
             * DI 找到对应的实现参考 com.zy.design.pattern.di.DITs
             * Class<? extends RPCMeat> aClass = rpcMeat.getClass();
             * 这里就简单点不做了
             * 假设就是通过DI找到了对应的实现
             */
            //服务器实现
            Object query = new RPCQuery();

            Object[] args = rpcMeat.getArgs();
            Class[] parameterTypes = null;
            if (args != null) {
                parameterTypes = new Class[args.length];
                for (int i = 0; i < args.length; i++) {
                    parameterTypes[i] = args[i].getClass();
                }
            }
            Method method = query.getClass().getMethod(rpcMeat.getMethod(), parameterTypes);
            Object invoke = method.invoke(query, rpcMeat.getArgs());
            os = socket.getOutputStream();
            objectOutputStream = new ObjectOutputStream(os);
            objectOutputStream.writeObject(invoke);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                is.close();
            }
            if (os != null) {
                os.close();
            }
            if (ObjectInput != null) {
                ObjectInput.close();
            }
            if (objectOutputStream != null) {
                objectOutputStream.close();
            }

        }


    }

}
